#include "llvm/LLVMContext.h"
#include "llvm/Module.h"

#include "llvm/PassManager.h"
#include "llvm/Bitcode/ReaderWriter.h"
#include "llvm/Analysis/Verifier.h"
#include "llvm/Assembly/Parser.h"
#include "llvm/Assembly/PrintModulePass.h"

#include "llvm/Support/CommandLine.h"
#include "llvm/Support/ManagedStatic.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/PrettyStackTrace.h"
#include "llvm/Support/SourceMgr.h"
#include "llvm/Support/Streams.h"
#include "llvm/Support/SystemUtils.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/System/Signals.h"
#include <iostream>
#include <fstream>

#include <memory>
#include "dis-as.h"
#include "trans.h"
using namespace llvm;


int main(int argc,char ** argv)
{
//	int i;
	char *cmd;	
	static cl::opt<std::string>
	InputFilename(cl::Positional, cl::desc("input code"), cl::init("-"));//the original file

	std::string InterFilename_hr;//intermediate file,it's a human-read file
	std::string InterFilename_bc;//intermediate file,it's a bc file
	std::string InterFilename_ptx;//intermediate file,it's a bc file
	std::string InterFilename_driver;//intermediate file,it's a bc file
	
	std::string bitcode_files;//this bitcode files contains the translated bitcode files as well as ones which runs the ptx codes 
	
	static cl::opt<std::string>
	OutputFilename_Final("o", cl::desc("Override output filename"),
               cl::value_desc("filename"));//the final bitcode file

	cl::ParseCommandLineOptions(argc, argv, "GPU edition\n");


	InterFilename_hr=ass_generator(InputFilename,InterFilename_hr,argc,argv);
	std::cout<<InterFilename_hr<<std::endl;


	InterFilename_driver=transform(InterFilename_hr,argc,argv);
	std::cout<<"bitcode	"<<InterFilename_driver<<std::endl;
	
	//bc_generator(InterFilename_driver,bitcode_files,argc,argv);
	//std::cout<<"ggggg	"<<InterFilename_driver.c_str()<<std::endl;
	cmd=(char *)malloc(strlen(InterFilename_driver.c_str())*2+strlen("llvm-as %s -o %s")+2+1);
	sprintf(cmd,"llvm-as %s -o %s.o",InterFilename_driver.c_str(),InterFilename_driver.c_str());	
	system(cmd);



	cmd=(char *)malloc(strlen(InterFilename_driver.c_str())+strlen("driver.o")+strlen("llvm-ld %s %s -o %s")+2+1);
	sprintf(cmd,"llvm-ld %s.o %s -lcuda -o %s",InterFilename_driver.c_str(),"driver.o","gpu");	
	system(cmd);

	return 1;
}
